// Check a value is zero with precision is epsilon
function gewIsZero(value, epsilon)
{
  if (!epsilon) {
    epsilon = GEW_MATH_EPSILON;
  }
  
  return Math.abs(value) < epsilon;
}

// Check 2 numbers is equal together depend on epsilon value
function gewIsEqual(number1, number2, epsilon)
{
  if (!epsilon) {
    epsilon = GEW_MATH_EPSILON;
  }
  return Math.abs(number1 - number2) < epsilon;
}
// Linear blend between v1&v2 : v = v1*(1-a)+v2*a
function gewMix(number1,number2,a)
{
  return number1*(1-a)+number2*a;
}

function gewMixVec(vec1, vec2, a)
{
  var result1 = vec1.mulScalar(1-a);
  var result2 = vec2.mulScalar(a);
  return result1.add(result2);
}

// Fixed point math
function gewFixedPointSize(type)
{
  if( type==GEW_FIXED_POINT_16) // (0_0_16)
    return 2;
  if( type==GEW_FIXED_POINT_32) // (1_15_16)
    return 4;
}
// Get smallest POT number that bigger ( or equal) than value
function gewSmallestPowerOfTwo(val)
{
  var pot_sampler = GEW_MATH_POT_SAMPLER;
  var num = pot_sampler.length;
  for(var i=0;i<num;i++)
  {
    if( pot_sampler[i] >= val)
      return pot_sampler[i];
  }
  return -1;
}

// Parsing binary data function : in little endian
function gewReadUInt32(data, offset)
{
  return ((data.charCodeAt(offset + 3) & 0xFF) * 16777216) +
  ((data.charCodeAt(offset + 2) & 0xFF) << 16) +
  ((data.charCodeAt(offset + 1) & 0xFF) << 8) +
  (data.charCodeAt(offset) & 0xFF);
}

function gewReadUInt16(data, offset)
{
  return ((data.charCodeAt(offset + 1) & 0xFF) << 8) +
  (data.charCodeAt(offset) & 0xFF);
}

function gewReadInt32(data,offset)
{
   var val =  ((data.charCodeAt(offset+3) & 0xFF) *16777216) +
               ((data.charCodeAt(offset+2) & 0xFF) << 16) +
               ((data.charCodeAt(offset+1) & 0xFF) << 8) +
               (data.charCodeAt(offset) & 0xFF);
   if(val>2147483648)
    val-=4294967296;
   return val;
}
function gewReadInt16(data, offset)
{
  var val =  ((data.charCodeAt(offset + 1) & 0xFF) << 8) +
              (data.charCodeAt(offset) & 0xFF);
  if(val > 32768)
    val-=65536;
  return val;
}

function gewReadUByte(data, offset)
{
  return data.charCodeAt(offset) & 0xFF;
}

function gewReadByte(data, offset)
{
  return data.charCodeAt(offset) & 0xFF - 128;
}

function gewReadFixed(data, offset, type, min,max)
{
  if(type==GEW_FIXED_POINT_32) 
  {
    var fp = gewReadUInt32(data, offset);    
    var scaleFactor = 65535;
    var isNegative = Math.abs(fp>>31);
    if (isNegative == 1) 
    {
      fp = fp & (~ (1 <<31));
      fp = -fp;
    }
    var re = fp / scaleFactor;
    return re;
  }
  else if(type==GEW_FIXED_POINT_16) 
  {
    var val = gewReadUInt16(data,offset);
    var factor = val/65535.0;
    return min*(1-factor)+max*factor;
  }
}